#ifndef FIRESYSYEM_H_
#define FIRESYSYEM_H_
#include "object.h"
#define FIRE_SIZE 150
class FireSystem3D {
public:
	FireSystem3D(GLint _size) {
		size=_size;
		isize=0;
		Zoom=-5;
		showLayer=isize+5;
		InitFire();
		Genenate();
	}

	GLuint RenderToTexture() 
	{
		glViewport(0, 0, 128, 128); 
		renderfire(); 
		glBindTexture(GL_TEXTURE_2D, Texture); 
		glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 128, 128, 0);
		glViewport(0, 0, 800, 600); 
		glClearColor(0.0f, 0.0f, 0.0f, 0.5f); 
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
			
		return Texture;
	}

private:

	void InitFire() {
		Texture = EmptyTexture(); 
		for (GLint i=0; i<size-1; i++) {
			for (GLint j=0; j<size-1; j++) {
				fire_life[i][j][isize]=rand()%255;
			}
		}
		for (int i=0;i<500;i++)
		fire_life[rand()%size][rand()%size][isize]=0;

	}
	Color getColor(GLfloat k) {
		Color c;
		if (k<64) {
			
			c.r=(GLubyte)((GLfloat)k/64*255);
			c.g=0;
			c.b=0;
		} else {
			if (k<128) {
				
				c.r=255;
				c.g=(GLubyte)((GLfloat)k/128*255);
				c.b=0;
			} else {
				if (k<192) {
					c.r=255;
					c.g=255;
					c.b=(GLubyte)((GLfloat)k/192*255);
				} else {
					c.r=255;
					c.g=255;
					c.b=255;
				}
			}
		}
		return (c);
	}
	void Genenate() {
		if (rand()>30000)		InitFire();
		for (GLint R=isize+1; R<showLayer+1; R++) {
			for (GLint i=1; i<size; i++) {
				for (GLint j=1; j<size; j++) {
					fire_life[i][j][R]=calcLife(i, j, R);
				}
			}
		}
	}


	GLuint EmptyTexture() 
	{
		GLuint txtnumber; 
		unsigned int* data; 

		data = (unsigned int*)new GLuint[((size * size)* 4 * sizeof(unsigned int))];
		ZeroMemory(data,((size * size)* 4 * sizeof(unsigned int)));
		
		glGenTextures(1, &txtnumber); 
		glBindTexture(GL_TEXTURE_2D, txtnumber); 
		glTexImage2D(GL_TEXTURE_2D, 0, 4, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
				data); 
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

		delete [] data; 

		return txtnumber; 
	}
	void renderfire() {
		Genenate();
		glDisable(GL_BLEND);
			
		glMatrixMode(GL_PROJECTION); 
		glPushMatrix(); 
		glLoadIdentity(); 
		gluOrtho2D( 0, size,0,size); 
		glMatrixMode(GL_MODELVIEW); 
		glPushMatrix(); 
		glLoadIdentity(); 
	
		GLfloat w=1;
		
		glDisable(GL_LIGHTING);
		glDisable(GL_TEXTURE_2D);
		for (int zd=showLayer; zd<showLayer+1; zd++) {
			for (int xd=10; xd<size-1; xd++) {
				for (int yd=10; yd<size-1; yd++) {
				
					glBegin(GL_QUADS); 
					renderVertex(xd, yd, 0, getColor(fire_life[xd][yd][zd]));
					renderVertex(xd, yd+w, 0,
							getColor(fire_life[xd][yd+1][zd]));
					renderVertex(xd+w, yd+w, 0,
							getColor(fire_life[xd+1][yd+1][zd]));
					renderVertex(xd+w, yd, 0,
							getColor(fire_life[xd+1][yd][zd]));
					glEnd();

				}
			
			}
		

		}

		glEnable(GL_LIGHTING);
		glEnable(GL_TEXTURE_2D);
		glMatrixMode(GL_PROJECTION); 
		glPopMatrix(); 
		glMatrixMode(GL_MODELVIEW); 
		glPopMatrix(); 

	}
	GLuint Texture;
	void renderVertex(GLfloat x, GLfloat y, GLfloat z, Color C) {
		glColor3ubv(C.V());
		glVertex3f((x-10)/(size-10)*(size+2), (y-10)/(size-10)*(size+2), z);
	}
	GLfloat calcLife(int x, int y, int z) {

		GLfloat T=fire_life[x][y][z]+fire_life[x-1][y-1][z-1]
				+fire_life[x][y-1][z-1]+fire_life[x-1][y][z-1]
				+ fire_life[x-1][y-1][z]+fire_life[x][y][z-1]
				+fire_life[x][y-1][z]+fire_life[x-1][y][z];
		T=T/8-rand()%6;
		if (T<0)
			return 0;
		else
			return T;
	}
	GLfloat Zoom;
	int size;
	int isize;
	int showLayer;
 
	GLfloat fire_life[FIRE_SIZE][FIRE_SIZE][15];
} F(32);

#endif /*FIRESYSYEM_H_*/
